import { getStyle } from '@/utils/DomUtil';
import { TooltipProps } from 'antd';
import React, {
  HTMLAttributes,
  useCallback,
  useEffect,
  useRef,
  useState,
} from 'react';
import styled from 'styled-components';
import { CustomTooltip } from '../CustomTooltip';

interface ITextProps {
  $lines?: number;
  $lineHeight?: string;
}

const TextLayout = styled.div<ITextProps>`
  &.text {
    position: relative;
    line-height: ${(props) => `${props.$lineHeight}`};
    /**关键代码-超出隐藏遮挡方块**/
    overflow: hidden;

    .text-inner {
      /**关键代码-解决高度设置为百分百失效的问题**/
      display: flex;
      .text-content {
        &.text-ellipsis {
          /**默认显示三行文字并且文字截断**/
          display: -webkit-box;
          -webkit-line-clamp: ${(props) => `${props.$lines}`};
          -webkit-box-orient: vertical;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: normal;
          word-wrap: break-word;
          word-break: break-all;
        }

        /** 设置float有文字环绕效果**/
        .text-toggle {
          float: right;
          clear: both;
          cursor: pointer;
          &::after {
            content: '展开';
            color: #006eff;
          }
        }
        /** 占位：占高度，宽度设为0px**/
        &::before {
          content: '';
          float: right;
          width: 0px;
          height: 100%;
          margin-bottom: ${(props) =>
            `-${props.$lineHeight}`}; /**和主体行高一样**/
        }
        /**遮挡方块：和.overflowtext-box背景颜色设置一样的，为了在不溢出文字的时候遮挡展开按钮**/
        &::after {
          content: '';
          width: 100%;
          height: 100%;
          position: absolute;
        }
      }
      /**选框（隐藏）**/
      #text-toggle-exp {
        display: none;
        /**选中时：显示行数加大**/
        &:checked {
          + .text-content {
            -webkit-line-clamp: 999;
            max-height: none;
            /**选中时：隐藏遮挡方块**/
            &::after {
              visibility: hidden;
            }
            /**选中时：文字显示收起**/
            .text-toggle::after {
              content: '收起';
              color: #006eff;
            }
          }
        }
      }
    }
  }
`;

interface Props<T = any> extends HTMLAttributes<T> {
  /** 输入文本、数字 */ text?: React.ReactNode;
  /** 行数，默认2行，溢出省略号 */ lines?: number;
  /** 个性化样式 */ style?: React.CSSProperties;
  /** 是否隐藏提示 */ hideTooltip?: boolean;
  /** antd框架Tooltip组件属性 */ tooltipProps?: TooltipProps;
}

export const TextEllipsis: React.FC<Props> = (props) => {
  const {
    text = '',
    lines = 2,
    className,
    style = {},
    onClick,
    children,
    hideTooltip,
    tooltipProps,
  } = props;

  const textStr = text || children;

  const textRef = useRef<any>(null);
  const [needEllipsis, setNeedEllipsis] = useState(false);
  const [lineHeight, setLineHeight] = useState('normal');

  const getPadding = (el: HTMLElement) => {
    const style = window.getComputedStyle(el, null);
    const paddingLeft = Number.parseInt(style.paddingLeft, 10) || 0;
    const paddingRight = Number.parseInt(style.paddingRight, 10) || 0;
    const paddingTop = Number.parseInt(style.paddingTop, 10) || 0;
    const paddingBottom = Number.parseInt(style.paddingBottom, 10) || 0;
    return {
      left: paddingLeft,
      right: paddingRight,
      top: paddingTop,
      bottom: paddingBottom,
    };
  };

  function isGreaterThan(a: number, b: number, epsilon = 0.03) {
    return a - b > epsilon;
  }

  const checkEllipsis = useCallback(() => {
    const item = textRef?.current;

    const range = document.createRange();
    range.setStart(item, 0);
    range.setEnd(item, item.childNodes.length);

    // 所有文字的宽度、高度
    const { width: rangeWidth, height: rangeHeight } =
      range.getBoundingClientRect();
    const { width: cellChildWidth, height: cellChildHeight } =
      item.getBoundingClientRect();

    const { top, left, right, bottom } = getPadding(item);
    const horizontalPadding = left + right;
    const verticalPadding = top + bottom;

    let lineHeight = getStyle(item, 'line-height');
    const fontSize = getStyle(item, 'font-size');

    if (lineHeight === 'normal') {
      lineHeight = `${parseFloat(fontSize) * 1.5}px`;
    }
    setLineHeight(lineHeight);

    if (
      isGreaterThan(rangeWidth + horizontalPadding, cellChildWidth) ||
      isGreaterThan(rangeHeight + verticalPadding, cellChildHeight) ||
      isGreaterThan(item.scrollWidth, cellChildWidth)
    ) {
      setNeedEllipsis(true);
    } else {
      setNeedEllipsis(false);
    }
  }, []);

  useEffect(() => {
    checkEllipsis();
    window.addEventListener('resize', checkEllipsis);
    return () => {
      window.removeEventListener('resize', checkEllipsis);
    };
  }, []);

  return (
    <CustomTooltip
      {...tooltipProps}
      title={!hideTooltip && needEllipsis ? textStr : null}>
      <TextLayout
        className="text"
        style={style}
        $lineHeight={lineHeight}
        $lines={lines}>
        <div className="text-inner">
          {needEllipsis && <input type="checkbox" id="text-toggle-exp" />}
          <div
            ref={textRef}
            onClick={onClick}
            className={[`text-content text-ellipsis`, className].join(' ')}
            style={
              {
                // WebkitLineClamp: lines,
              }
            }>
            {needEllipsis && (
              <label className="text-toggle" htmlFor="text-toggle-exp"></label>
            )}
            {textStr}
          </div>
        </div>
      </TextLayout>
    </CustomTooltip>
  );
};
